﻿using System;
using System.Net;
using System.Threading;

using UdpTransceiver;
using ParametersParser;
using Communicator;


namespace ApplicationMaster
{
    /// <summary>
    /// Тестовое приложение использования коммуникатора в режиме ведущего узла.
    /// Для тестирования установите этот проект в качестве запускающего
    /// </summary>
    class Program
    {
        /// <summary>
        /// Признак активного полета
        /// </summary>
        static bool Flight = true;
        
        static Communicator.Communicator Communicator;

        /// <summary>
        /// Обработчик события отсылки непустого пакета
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="a"></param>
        static public void SentPackageHandler(object sender, EventArgs a)
        {
            // Здесь обратывается событие отправки пакета
            Console.WriteLine("\nОтправлен пакет данных");
        }

        /// <summary>
        /// Обработчик события приема непустого пакета
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="a"></param>
        static public void ReceivedPackageHandler(object sender, EventArgs a)
        {
            // Здесь обратывается событие приема пакета
            Console.WriteLine("\nПринят пакет данных");            
        }

        static public void InputParametersChangedHandler(object sender, EventArgs a)
        {
            // Здесь обратывается событие изменения входных параметров
            Console.WriteLine("\nИзменились входные параметры");
            string value = Communicator.GetParameterValueByName("STOP_FLIGHT");
            // Если пришел сигнал окончания остановки полета, то завершаем работу
            if (value == "1")
                Flight = false;
            else if (value == "0")
                Flight = true; 
        }

        /// <summary>
        /// Обработчик события обмена коммуникатора (приема или отсылки любого инфо-пакета)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="a"></param>
        static public void ExchangeHandler(object sender, EventArgs a)
        {
            Console.Clear();
            Console.WriteLine("\nПроизошел какой-то обмен пакетами");     
        }

        static public void CommunicatorTickHandler(object sender, EventArgs a)
        {
            // Здесь обратывается событие окончания цикла коммуникатора
            Console.WriteLine("\nЗакончен цикл коммуникатора");
            Console.WriteLine("{0}\n Input parameters:", DateTime.Now);
            foreach (Parameter Item in Communicator.Parameters)
                if (Item.Direction == ParameterDirection.input || Item.Direction == ParameterDirection.inpout)
                    Console.Write("{0} = {1};\t", Item.Name, Item.Value);
            Console.WriteLine("\nOutput parameters");
            foreach (Parameter Item in Communicator.Parameters)
                if (Item.Direction == ParameterDirection.output || Item.Direction == ParameterDirection.inpout)
                    Console.Write("{0} = {1};\t", Item.Name, Item.Value);
        }
   
        static void Main(string[] args)
        {
            Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Program_UnhandledException);

            // Создаем экземпляр коммуникатора
            Communicator = new Communicator.Communicator();

            Console.WriteLine("Start exchange? (y/n)");
            if (Console.ReadLine() == "y")
            {
                Console.WriteLine("Initializing communicator...( Q - exit )");

                // Подписываемся на события коммуникатора
                Communicator.DataSent += SentPackageHandler;
                Communicator.DataReceived += ReceivedPackageHandler;
                Communicator.DataExchange += ExchangeHandler;
                Communicator.InputParameterChanged += InputParametersChangedHandler;
                Communicator.ExchangeTick += CommunicatorTickHandler;

                // Запускаем коммуникатор для обмена
                Communicator.Start();

                // Подписываемся на отправку и получение параметров
                // Исходящие
                Communicator.AddParameter("ALTITUDE", ParameterDirection.output);
                //Communicator.AddParameter("AIRSPEED", ParameterDirection.output);
                // Входящие
                Communicator.AddParameter("STOP_FLIGHT", ParameterDirection.input);

                Communicator.SetParameterValueByName("ALTITUDE", "0");
                int i = 0;
                bool Rise = true;
                int k = 0;
                // Летим
                while (Flight)
                {
                    if (i < 15 && Rise == true)
                        i++;
                    else if (i >= 15)
                        Rise = false;
                    else if (i >= 15 && Rise == false)
                        i--;
                    else if (i <= 0)
                        Rise = true;

                        //if (k < 2000)
                        //    k = k + 1;
                        // Меняем значения выходных параметров
                       // Communicator.SetParameterValueByName("AIRSPEED", i.ToString());
                    Communicator.SetParameterValueByName("ALTITUDE", i.ToString());

                    // Типа занимаемся чем-то еще
                    Thread.Sleep(5000);
                    ConsoleKeyInfo cki = new ConsoleKeyInfo();

                    // Выход по нажатию клавиши Ку
                    if (Console.KeyAvailable == true)
                    {
                        cki = Console.ReadKey(true);
                        if (cki.Key == ConsoleKey.Q)
                            Flight = false;
                    }
                }
                Communicator.Stop();
            }
  
        }

        
        static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Console.WriteLine(((Exception)e.ExceptionObject).Message );
        }
           
    }
}
